<?php

namespace app\controllers\h5;

use app\commission\PaidFinish;
use app\controllers\h5\base\H5Controller;
use app\models\order\Order;
use app\models\order\OrderItem;
use app\models\Sms;
use app\models\system\SetApp;
use app\models\system\SetBasic;
use app\models\system\SetFlow;
use app\models\system\SetSms;
use app\models\user\User;
use app\models\user\User as Model;
use app\controllers\h5\services\User as Service;
use app\models\user\UserAccount;
use app\models\user\UserLevel;
use app\models\UserBalance;
use app\services\Chain;
use app\util\JWT;
use app\util\Qrcode;
use app\util\Util;
use Yii;
use function Symfony\Component\String\s;

/**
 * Class UserController
 * @package app\controllers\h5
 */
class UserController extends H5Controller
{
    /**
     * Login
     *
     * @return array|string[]|\yii\web\Response
     */
    public function actionLogin()
    {
        $mobile = $this->post('mobile');
        $password = $this->post('password');

        if (!$mobile || !$password) {
            return $this->fail('请输入正确的用户名或者密码');
        }

        // login
        $user = Service::login($mobile, $password);
        if (!empty($user)) {
            if ($user['status'] == Model::$statusMapping['CLOSE']) {
                return $this->fail('正在关小黑屋中....');
            }

            // login ip
            $user->login_ip = Util::getClientIp();

            // 判断是公众号登录
            $user->is_wx = 1;
            $user->save();

            // generate token
            $token = JWT::createToken(
                [
                    'mobile' => $mobile,
                    'id' => $user['id'],
                ],
                Yii::$app->params['JWT_H5_KEY'],
                Yii::$app->params['JWT_H5_EXPIRED']
            );

            return $this->successEncode([
                'token' => $token,
                'id' => $user['id'],
            ], '登录成功');
        }

        return $this->fail('登录失败,请检查手机号码或者密码是否正确');
    }

    public function actionRegister()
    {
        $data = $this->post();

        // check user isExist
        $user = Model::findOne(['mobile' => $data['mobile']]);
        if ($user) {
            return $this->fail('此手机号码已经被注册了');
        }

        // referrer mobile or id
        if (isset($data['referrer']) && $data['referrer']) {
            $referrer = Model::find()
                ->where(['id' => $data['referrer']])
                ->orWhere(['mobile' => $data['referrer']])
                ->one();
            if (!$referrer) {
                return $this->fail('推荐人错误');
            }
            $data['referrer_id'] = $referrer->id;

            // check referrer
            // if (Service::checkReferrer($data['id'], $data['referrer_id'])) {
            //     return $this->fail('推荐人错误!!!');
            // }
        }

        // level
        $data['level'] = UserLevel::$keys['none'];
        $data['sort'] = 9999;

        // register
        $data = ['User' => $data];
        $model = new Model();
        if ($model->load($data) && $model->save()) {

            // user account
            $account = new UserAccount();
            $account->user_id = $model->id;
            if ($account->save()) {
                return $this->success('注册成功');
            }
        }


        return $this->fail('注册失败');
    }

    /**
     * Get user info
     *
     * @return array|string[]|\yii\web\Response
     */
    public function actionGetInfo()
    {
        $user = Service::getInfo($this->user->id);

        if ($user !== false) {
            // 等级设置
            // $value = 0;
            // if ($user['v5'] > 0) {
            //     $value = $user['v5'];
            // }
            // else if ($user['v4'] > 0) {
            //     $value = $user['v4'];
            // }
            // else if ($user['v3'] > 0) {
            //     $value = $user['v3'];
            // }
            // else if ($user['v2'] > 0) {
            //     $value = $user['v2'];
            // }
            // else if ($user['v1'] > 0) {
            //     $value = $user['v1'];
            // }
            // $level = UserLevel::find()
            //     ->where(['value' => $value])
            //     ->select(['display'])
            //     ->scalar();
            //
            // $user['vipLevel'] = $level;
            //
            // // svip 等级
            // $str = [];
            // if ($user['c1'] > 0) {
            //     $str[] = UserLevel::find()
            //         ->where(['value' => $user['c1']])
            //         ->select(['display'])
            //         ->scalar();
            // }
            // if ($user['c2'] > 0) {
            //     $str[] = UserLevel::find()
            //         ->where(['value' => $user['c2']])
            //         ->select(['display'])
            //         ->scalar();
            // }
            //
            // $level = implode(' ', $str);
            // $user['svipLevel'] = $level;

            return $this->successEncode($user);
        }

        return $this->fail('获取用户信息失败');
    }

    public function actionWx()
    {
        $set = SetFlow::getLastOne();
        return $this->success(['wx' => $set->wx == 1]);
    }

    /**
     * Register agreement
     *
     * @return array|string[]|\yii\web\Response
     */
    public function actionAgreement()
    {
        $model = SetBasic::getLastOne();

        return $this->success($model->agreement);
    }

    /**
     * Get verify code
     *
     * @return array|string[]|\yii\web\Response
     * @throws \AlibabaCloud\Client\Exception\ClientException
     */
    public function actionVerifyCode()
    {
        $mobile = $this->post('mobile');
        if (!$mobile) {
            return $this->fail('请输入手机号码');
        }

        $set = SetSms::getLastOne();

        if (Sms::isSend($mobile)) {
            return $this->fail('请' . $set->timeout . '分钟之后再来...');
        }

        $start = pow(10, $set->len - 1);
        $end = pow(10, $set->len) - 1;
        $code = mt_rand($start, $end);
        if (Sms::generateCode($mobile, $code)) {
            $data = ['timeout' => $set->timeout];

            // is simulate
            if ($set->switch == 1) {
                $data['code'] = $code;
            }

            return $this->successEncode($data, '验证码已经成功发送,请注意查收!');
        }

        return $this->fail('获取验证码失败');
    }

    /**
     * Check verify
     *
     * @return array|string[]|\yii\web\Response
     */
    public function actionCheckVerify()
    {
        $mobile = $this->post('mobile');
        $code = $this->post('code');

        if (Sms::verify($mobile, $code)) {
            return $this->success();
        }

        return $this->fail('验证码错误');
    }

    /**
     * Forget password
     *
     * @return array|string[]|\yii\web\Response
     */
    public function actionForgetPassword()
    {
        $data = $this->post();

        $model = Model::findOne(['mobile' => $data['mobile']]);
        if (!$model) {
            return $this->fail('手机号码错误');
        }
        if ($model->status == Model::$statusMapping['CLOSE']) {
            return $this->fail('您已经被拉黑,无法修改');
        }

        $model->password = $data['password'];

        if ($model->save()) {
            return $this->success();
        }

        return $this->fail('操作失败');
    }

    /**
     * Change password
     *
     * @return array|string[]|\yii\web\Response
     */
    public function actionChangePassword()
    {
        $data = $this->post();

        if ($data['password'] != $data['password2']) {
            return $this->fail('两次密码不相同');
        }

        if (strlen($data['password']) < 6) {
            return $this->fail('长度不能小于6位');
        }

        $user = Model::findOne(['id' => $this->user->id]);

        if ($data['old_password'] != $user->password) {
            return $this->fail('旧密码错误');
        }

        $user->password = $data['password'];
        if ($user->save()) {
            return $this->success();
        }

        return $this->fail('操作失败');
    }

    /**
     * check wx login open
     *
     * @return array|string[]|\yii\web\Response
     */
    public function actionWxLogin()
    {
        $model = SetApp::getLastOne();

        return $this->successEncode($model->open_wx_login);
    }

    /**
     * Is it need referrer
     *
     * @return array|string[]|\yii\web\Response
     */
    public function actionNeedReferrer()
    {
        $model = SetFlow::getLastOne();

        return $this->successEncode($model->register_referrer);
    }

    // 商家信息
    public function actionIsMerchant()
    {
        $id = $this->user->id;

        $model = Model::findOne(['id' => $id]);
        if ($model->is_merchant == 0) {
            return $this->fail('您暂无收银系统');
        }

        $set = SetApp::getLastOne();
        $string = $set->domain . '/user/shop-pay/' . $id;
        $name = '/shop-scan/' . $id . '-shop.jpg';

        Qrcode::generate($string, $name, 365);

        return $this->successEncode([
            'id' => $model->id,
            'url' => $set->domain . $name,
            'string' => $string,
        ]);
    }

    // 收款信息
    public function actionMerchantList()
    {
        $page = intval($this->post('page', $this->page));
        $pageSize = intval($this->post('pageSize', $this->pageSize));

        $query = Order::find()
            ->where(['supplier_id' => $this->user->id]);

        $totalCount = $query->count();
        $totalPage = ceil($totalCount / $pageSize);

        $list = $query->orderBy(['update_time' => SORT_DESC])
            ->offset(($page - 1) * $pageSize)
            ->limit($pageSize)
            // ->with(['item', 'item.product', 'item.product.mainImage'])
            ->with(['item',])
            ->asArray()
            ->all();

        return $this->successEncode([
            $this->list => $list,
            $this->totalCount => (int)$totalCount,
            $this->totalPage => $totalPage,
            $this->currentPage => $page
        ]);
    }

    public function actionMerchantView()
    {
        $id = $this->post('id');
        $model = Model::find()
            ->where(['id' => $id])
            ->select(['id', 'mobile', 'nickname', 'is_merchant'])
            ->asArray()
            ->one();

        if ($model && $model['is_merchant'] == 1) {
            if ($model['nickname']) {
                $model['nickname'] = base64_decode($model['nickname']);
            }

            // 会员帐户
            $account = UserAccount::findOne(['user_id' => $this->user->id]);

            return $this->successEncode([
                'merchant' => $model,
                'user' => $account->toArray(),
            ]);
        }

        return $this->fail('不存在该商家');

    }

    // 扫码支付给商家
    public function actionScanPay()
    {
        $id = $this->post('id');
        $amount = $this->post('amount', 0);

        if ($amount <= 0) {
            return $this->fail('金额错误');
        }

        $transaction = \Yii::$app->db->beginTransaction();

        try {

            // 使用积分, 余额支付
            $account = UserAccount::findOne(['user_id' => $this->user->id]);
            $use_money = $amount;
            $use_balance = 0;
            $use_score = 0;

            if ($use_money > 0) {
                if ($account->score >= $use_money) {
                    $use_score = $use_money;
                    $use_money = 0;
                } else {
                    $use_score = $account->score;
                    $use_money -= $account->score;
                }
            }

            if ($use_money > 0) {
                if ($account->balance >= $use_money) {
                    $use_balance = $use_money;
                    $use_money = 0;
                } else {
                    $use_balance = $account->balance;
                    $use_money -= $account->balance;
                }
            }

            // 创建订单
            $order = new Order();
            $order->sn = Order::generateSn();

            $order->user_address = 0;
            $order->user_id = $this->user->id;
            $order->total_pay = $amount;
            $order->use_money = $use_money;
            $order->use_score = $use_score;
            $order->use_balance = $use_balance;
            // 保存扫给谁的
            $order->supplier_id = $id;
            $order->pay_type_name = '线下扫码';
            $order->pay_type = '121';
            $order->request_params = '';
            $order->status = Order::$statusMapping['NON_PAYMENT'];
            $order->total_quantity = 1;

            // 日志 (可能要返奖)
            $chain = Chain::getReferrerChain($order->user_id);
            $log = [
                // 'user' => User::findOne(['id' => $order->user_id])->toArray(),
                'user' => User::find()->where(['id' => $order->user_id])->with(['level0'])->asArray()->one(),
                'chain' => $chain,
            ];
            $log = json_encode($log);
            $order->log = $log;

            $r=$order->save();
            if (!$r) {
                throw new \Exception('创建支付订单错误');
            }

            $item = new OrderItem();
            $item->order_id = $order->id;
            $item->quantity = 1;
            $item->product_id = 0;
            $item->product_sku_id = 0;
            $item->selected_sku_value = '';
            $item->selected_sku_text = '';
            $item->freight = 0;
            $item->price = 0;
            $item->score = 0;
            $item->save();

            if ($use_balance > 0) {
                UserBalance::addLog($this->user->id,
                    $account->balance, -$use_balance, $account->balance - $use_balance, '线下扫码', $order->id);
            }

            if ($use_balance > 0) {
                $account->balance -= $use_balance;
                $account->lock_balance += $use_balance;
                $account->save();
            }
            if ($use_score > 0) {
                $account->score -= $use_score;
                $account->lock_score += $use_score;
                $account->save();
            }

            if ($use_money <= 0) {
                PaidFinish::order($order);

                $order->status = Order::$statusMapping['FINISH'];
                $order->save();
            }


            $transaction->commit();
            return $this->successEncode([
                'order_id' => $order->id,
                'use_money' => $use_money,
            ]);

        } catch (\Exception $e) {
            $transaction->rollBack();
            // return $this->fail($e->getMessage() . ' ' . $e->getLine(). ' ' . $e->getFile());
            return $this->fail($e->getMessage());
        }
    }
}